/**
 * 
 */
package asia.syimyuzya.android.prime;

import android.os.AsyncTask;

/**
 * 用於素數判定之異步任務.
 * <p>
 * 其{@link AsyncTask#execute(Object...) execute(String...)}方法接收String參數.
 * 惟第一個參數會被處理. 該字串須表示一個64位有符號整數（可以為負）.
 * <p>
 * 使用樸素的試除法，處理大數時會比較慢.
 * <p>
 * 該過程為異步執行.
 * 用者須覆寫{@link #onComplete(Integer)}作為作為回調函數.
 * 回調函數接收一個測試結果代碼作為參數.
 * 結果代碼意義於內部類{@link ResultCode}中定義.
 * 
 * @see AsyncTask
 * @see PrimeTest.ResultCode
 * 
 * @author syimyuzya
 */
public abstract class PrimeTest extends
		AsyncTask<String, Void, Integer> {

	/**
	 * 定義素數判斷結果代碼意義.
	 * 
	 * @see PrimeTest
	 */
	public class ResultCode {
		/** 未提供字串，或所提供字串為空串. */
		public final static int EMPTY = 0;
		/** 所提供字串並非數字. */
		public final static int NAN = 1;
		/** 非素數亦非合數（0或1）. */
		public final static int NONE = 2;
		/** 素數. */
		public final static int PRIME = 3;
		/** 合數. */
		public final static int COMPOSITE = 4;
	}
	
	/**
	 * 任務完成後之回調函數.
	 * 
	 * @param resultCode 素數測試結果代碼.
	 */
	protected abstract void onComplete(Integer resultCode);
	
	@Override
	protected Integer doInBackground(String... strings) {
		if (strings.length==0 || strings[0].length()==0) {
			return ResultCode.EMPTY;
		}
		long x;
		try {
			x = Long.parseLong(strings[0]);
		} catch (NumberFormatException e) {
			return ResultCode.NAN;
		}
		if (x<0) {
			x = -x;
		}
		if (x<2) {
			return ResultCode.NONE;
		}
		for (long i = 2; i*i<=x; i++) {
			if (x%i==0) {
				return ResultCode.COMPOSITE;
			}
		}
		return ResultCode.PRIME;
	}
	
	@Override
	protected void onPostExecute(Integer result) {
		super.onPostExecute(result);
		onComplete(result);
	}

}
